<script setup>
import {useDialog} from "jiuqi-ui";
import {reactive, onMounted, ref, provide, inject, watch} from "vue";
import DriverTable from "./DriverTable.vue";
import TabsEditComponent from "./DriverGroupTabsEdit.vue";
import TabsView from "../common/tabsView.vue";
import YesNoCancelDialog from "../common/YesNoCancelDialog.vue";


//================================================【公用相关】============================================================
//编辑类型  新增 0   编辑  1   删除 2  拖拽 3
const editType = new ref(-1)

//创建页签列表(存储所有动因分组)
const tabs = reactive([])

// 当前右键点击索引（数组索引，无业务含义）
const rightActiveIndex = ref(0)
// 当前右键点击内容
const rightActiveName = ref('')

// 当前激活页签索引（数组索引，无业务含义）
const currentActiveTabIndex = ref(0)
// 当前激活页签key(动因分组主键)
const currentActiveTabKey  = ref('')
// 当前激活页签名称
const currentActiveTabTitle = ref('')

// 激活页签组件
const curDriverRef = ref()

//三态对话框
const yncInfo = reactive({visible:false,content:'',putOffParam:{},putOffSelect:{}})

//编辑动因
function editDriverGroup(param) {
        let editedTabItem = reactive({
            key: tabs[rightActiveIndex.value].key,
            title: param,
            order: tabs[rightActiveIndex.value].order,
        })
        context.getPlugin('http').post(`abc/model/driverGroup/update`, editedTabItem).then(() => {
            initTabs()
        });
}

//变更页签顺序
function changeOrder(dragIndex, targetIndex) {
    context.getPlugin('http').get(`abc/model/driverGroup/changeOrder/${currAbcModelGuid.value}/${dragIndex}/${targetIndex}`).then(() => {
        initTabs(targetIndex);
    });
}
//同步激活页签
function asyncTabKey(newValue) {
  //设置 当前激活页签索引
  currentActiveTabIndex.value = tabs.findIndex(preFindItem => {
    return preFindItem.key === newValue
  })
  //设置 当前激活页签名称
  currentActiveTabTitle.value = tabs[currentActiveTabIndex.value].title
}
//================================================【组件通信】============================================================
//请求工具
const context = inject('context')

//当前模型ID
const {currAbcModelGuid} = inject('abcmodel')

//控制编辑页签显示与隐藏
const editComponentVisiable = ref(false);
provide('editComponentVisiable',editComponentVisiable)

//当前激活页签名称
provide('currentActiveTabTitle',currentActiveTabTitle)

//当前激活页签下标
provide('currentActiveTabKey',currentActiveTabKey)

//宏显式暴露
defineExpose({
    saveDriver,abandonSaveDriver,checkTabContentChanged
})

//由 父组件 控制的 激活页签名称
const props = defineProps({
    fatherControlPaneName:{
        type:Object,
        required:false
    }
});

//处理子组件传来的参数
function processParam(param) {
        //编辑操作
        editDriverGroup(param);
}
//================================================【组件属性】============================================================
//父组件控制 当前页面激活页签
watch(()=>props.fatherControlPaneName,(newValue)=>{
    if (newValue !== undefined)
        currentActiveTabKey.value = newValue.key === undefined ? currentActiveTabKey.value :  newValue.key
},{deep:true,immediate:true})

//监听当前激活页签下标，更新当前激活页签名称
watch(()=>currentActiveTabKey.value,(newValue)=>{
   asyncTabKey(newValue);
})
//================================================【普通方法】============================================================
//==================================================================【上方主体---保存动因】
function saveDriver() {
    return new Promise((resolve, reject) => {
        curDriverRef.value.save().then(()=>{
            resolve()
        }).catch(() => {
            reject()
        })
    });
}
//==================================================================【上方主体---不保存动因】
function abandonSaveDriver() {
    return new Promise((resolve, reject) => {
        curDriverRef.value.abandonPreSaveContent().then(()=>{
            resolve()
        }).catch(() => {
            reject()
        })
    });
}
//==================================================================【上方主体---关闭ncell编辑状态】
function checkTabContentChanged() {
    //手动关闭编辑状态
    return curDriverRef.value.closeEditorAndCheck();
}
//==================================================================【初始化页签列表】
function initTabs(targetIndex){
    return new Promise((resolve, reject) => {
        // 需要访问后端获取数据
        context.getPlugin('http').get(`abc/model/driverGroup/list/${currAbcModelGuid.value}`).then((res) => {
            tabs.splice(0,tabs.length,...res.data)
            //设置当前激活页签
            if (tabs.length > 0) {
                //页签初始状态，定位到第一个页签
                if (editType.value === -1) {
                    currentActiveTabKey.value = tabs[0].key

                    //新增操作，自动激活新增页签
                } else if (editType.value === 0) {
                    currentActiveTabKey.value = tabs[tabs.length - 1].key;

                    //编辑操作（重命名），自动定位到操作位置
                } else if (editType.value === 1) {
                    currentActiveTabKey.value = tabs[rightActiveIndex.value].key;

                    //删除操作
                } else if (editType.value === 2){
                    //删除页签 是 最后一个页签(注意：此时的tabs是删除后的数组，所以用tabs.length判断是否为删除前的最后一个页签)
                    if (currentActiveTabIndex.value === tabs.length){
                        currentActiveTabKey.value = tabs[tabs.length - 1].key;

                    //删除页签 不是 最后一个页签
                    } else{

                        currentActiveTabKey.value = tabs[currentActiveTabIndex.value].key;
                    }

                    //移动操作，自动定位到目标移动位置
                } else if (editType.value === 3) {
                    currentActiveTabKey.value = tabs[targetIndex].key;

                    //需要额外注意：对于移动操作，currentActiveTabKey 前后对应同一个值，不会触发监听
                    //需要手动触发，主要是为了更新 currentActiveTabIndex
                    asyncTabKey(currentActiveTabKey.value)
                }
            } else {
                //如果tabs为空，手动设置默认动因分组
                handleTabsAdd()
            }

            //清空操作状态
            editType.value = -1
            resolve()
        }).catch(()=>{
            reject()
        })
    });
}
//==================================================================【底部页签---添加页签】
function handleTabsAdd() {
    editType.value = 0
    beforeLeaveTab(null)
}
//==================================================================【底部页签---展示右键菜单】
function showContextMenu(data) {
    rightActiveIndex.value= tabs.findIndex((preFindItem) => preFindItem.key === data.key);
    rightActiveName.value = data.title
}
//==================================================================【底部页签---选中右键菜单】
function toSelectContextMenu(processType) {
    if (tabs[rightActiveIndex.value].key !== currentActiveTabKey.value){
        if (processType === 'update') {
            yncInfo.putOffParam.processType = processType
            beforeLeaveTab(tabs[rightActiveIndex.value])
        }
        if (processType === 'delete') {
            useDialog().warning({
                content:`确认删除[${rightActiveName.value}]吗？`,
                onOk:()=>{
                    let preDeleteTabItem = tabs[rightActiveIndex.value]
                    context.getPlugin('http').get(`abc/model/driverGroup/delete/${preDeleteTabItem.key}`)
                        .then(() => {
                            tabs.splice(rightActiveIndex.value,1)
                        })
                },
                onCancel:()=>{
                    //清空操作状态
                    editType.value = -1
                }
            });
        }
    }else {
        //==================================================================【底部页签---删除页签】
        if (processType === 'delete'){
            useDialog().warning({
                content:`确认删除[${rightActiveName.value}]吗？`,
                onOk:()=>{
                    editType.value = 2
                    let preDeleteTabItem = tabs[rightActiveIndex.value]
                    context.getPlugin('http').get(`abc/model/driverGroup/delete/${preDeleteTabItem.key}`)
                        .then(() => {
                            initTabs()
                        })
                },
                onCancel:()=>{
                    //清空操作状态
                    editType.value = -1
                }
            });

            //==================================================================【底部页签---编辑页签】
        } else {
            editType.value = 1
            editComponentVisiable.value = true
        }
    }
}
//==================================================================【底部页签---拖拽时触发】
function handleDragDrop (dragIndex,targetIndex,dragTabItem,targetTabItem) {
    editType.value = 3
    if (dragTabItem.key !== currentActiveTabKey.value){
        yncInfo.putOffParam.dragIndex = dragIndex;
        yncInfo.putOffParam.targetIndex = targetIndex;
        beforeLeaveTab(targetTabItem)
    }else {
        changeOrder(dragIndex, targetIndex)
    }
}
//==================================================================【底部页签---离开页签前】
//由 页签A 离开至 页签B
function beforeLeaveTab(oldTabItem,newTabItem) {
    //占位使用oldTabItem
    console.log('oldTabItem',oldTabItem)
    if (curDriverRef.value && curDriverRef.value.getSaveStatus()) {
        yncInfo.content = `是否保存动因分组[${currentActiveTabTitle.value}]？`;
        yncInfo.visible = true;
        yncInfo.putOffSelect = newTabItem;
        //中止离开操作
        return false;
    }else {
        leavePutOff().then(()=>{
            yncInfo.content = '';
            yncInfo.putOffParam = {}
            yncInfo.putOffSelect = {}
            yncInfo.visible = false
            //继续离开操作
            return true
        });
    }
}
//==================================================================【底部页签---离开页签延迟事件】
function leavePutOff() {
    return new Promise((resolve) => {
        //增 改 删 拖拽 触发的离开前事件
        if (editType.value === 0) {
            context.getPlugin('http').post(`abc/model/driverGroup/add`, {belongModelId: currAbcModelGuid.value})
                .then(() => {
                    initTabs().then(resolve())
                })
        } else if (yncInfo.putOffParam.processType === 'update') {
            editType.value = 1
            editComponentVisiable.value = true
            resolve()
        } else if (editType.value === 3) {
            changeOrder(yncInfo.putOffParam.dragIndex, yncInfo.putOffParam.targetIndex)
            resolve()
        }else {
            //单纯点击其他页签触发的 离开前事件
            currentActiveTabKey.value = yncInfo.putOffSelect.key
            resolve()
        }
    });
}

//==================================================================【三态对话框---确认操作】
function selectYes() {
    saveDriver().then(()=>{
        leavePutOff().then(()=>{
            yncInfo.content = '';
            yncInfo.putOffParam = {}
            yncInfo.putOffSelect = {}
            yncInfo.visible = false
        })
    })
}
//==================================================================【三态对话框---拒绝操作】
function selectNo() {
    abandonSaveDriver().then(()=>{
        leavePutOff().then(()=>{
            yncInfo.content = '';
            yncInfo.putOffParam = {}
            yncInfo.putOffSelect = {}
            yncInfo.visible = false
        })
    })
}
//================================================【生命周期】============================================================
onMounted(()=>{
    initTabs();
})
</script>

<template>
    <j-layout class="layout">
        <j-content>
            <!--    上方主体   -->
            <DriverTable ref="curDriverRef"></DriverTable>
            <!--    底部页签   -->
            <tabs-view
                label="title"
                name="key"
                :tabs="tabs"
                v-model:curName="currentActiveTabKey"
                :extendTab="false"
                :before-leave="beforeLeaveTab"
                @add-tab="handleTabsAdd"
                @on-contextmenu="showContextMenu"
                @on-click-menu="toSelectContextMenu"
                @on-drag-drop="handleDragDrop"
            ></tabs-view>
            <!--    重命名对话框   -->
            <TabsEditComponent
                :show="editComponentVisiable"
                :edit-value="rightActiveName"
                @selfConfirmReturnParam="processParam"
            >
            </TabsEditComponent>
            <!--    三态对话框   -->
            <yes-no-cancel-dialog
                :visible="yncInfo.visible"
                :content="yncInfo.content"
                @yes="selectYes"
                @no="selectNo"
                @cancel="yncInfo.visible = false"
            ></yes-no-cancel-dialog>
        </j-content>
    </j-layout>
</template>

<style lang="less" scoped>

</style>
